/*
*  Impp - Instant Messenger
*
*  Copyright (C) 2008  Oliver Schneider
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#include "BuddyList.h"

#include <iostream>
#include <wx/toolbar.h>
#include <wx/menu.h>
#include <wx/sysopt.h>
#include <wx/font.h>
#include <wx/filedlg.h>

#include "../StdUserInterfaceModule/Icons.h"
#include "StatusMessageDialog.h"
#include "AccountDetails.h"
#include "../../core/Impp.h"
#include "../../core/interfaces/iProtocol.h"
#include "../../protocols/oscar/OscarServerCon.h"


namespace Impp {


BEGIN_EVENT_TABLE(BuddyList, wxFrame)
  EVT_CLOSE(BuddyList::onClosed)
  EVT_TOOL(ID_TOOL_MAINMENU, BuddyList::onMainMenu)
  EVT_TOOL_RANGE(ID_BUDDYLIST_BUDDY_PRIORITY_CHANGE, ID_BUDDYLIST_BUDDY_PRIORITY_NOT_LOW, BuddyList::onShowBuddiesWithPriority)
  EVT_TOOL(ID_BUDDYLIST_BUDDY_SHOW_OFFLINE, BuddyList::onCheckTool)
  EVT_TOOL(ID_BUDDYLIST_BUDDY_SHOWAVAS, BuddyList::onCheckTool)
  EVT_TOOL(ID_BUDDYLIST_GROUPS_USE, BuddyList::onCheckTool)
END_EVENT_TABLE()


IMPLEMENT_DYNAMIC_CLASS(StdBuddyListModule, iBuddyList)

BuddyList::BuddyList()
	: wxFrame(NULL, ID_BUDDYLIST, _T("Impp Alpha"),wxDefaultPosition,wxDefaultSize,wxMAXIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCAPTION|wxCLOSE_BOX|wxCLIP_CHILDREN|wxFRAME_NO_TASKBAR),
	buttonList(ID_BUDDYLIST_HIGHEST)
{

    Impp* impp = Impp::exemplar();
    dbModule = impp->getDatabase()->getModule(wxT("BuddyList"));

	iUserInterface* ui = Impp::exemplar()->getModuleManager()->getUserInterfaceModule();
	if(ui == NULL){
		wxLogError(wxT("BuddyList: No userinterface found, can not create BuddyList"));
	}

	wxIcon icon;
	icon.CopyFromBitmap(ui->getIcons()->getSpecialBitmap(BITMAP_IMPP_ICON));
	SetIcon(icon);

    // set the frame icon
    //SetIcon(wxICON(sample));

	wxPanel* rootPane = new wxPanel(this,wxID_ANY);
	wxPanel* infoPane = new AccountDetails(rootPane);
	sizer = new wxBoxSizer(wxVERTICAL);


	searchField = new SearchField(this, rootPane,ID_SEARCH);
	list = new BuddyTreeList(rootPane,ID_TREELIST);
	actionPanel = new ActionPanel(this, rootPane, wxID_ANY);

	 wxToolBar* toolbar = CreateToolBar();

	#ifdef __WXMSW__
	 	if((wxTheApp->GetComCtl32Version() >= 600 && ::wxDisplayDepth() >= 32)){
	 		 wxSystemOptions::SetOption(wxT("msw.remap"), 2);
	 	}
	#endif


	 if(toolbar){
		 iIcons* icons = ui->getIcons();
		 wxBitmap groupTogle = icons->getBitmap(wxT("icons/main/group.png"));
		 wxBitmap avasTogle = icons->getBitmap(wxT("icons/main/avas.png"));
		 wxBitmap priority = icons->getBitmap(wxT("icons/main/priority.png"));

		 toolbar->AddTool(ID_TOOL_MAINMENU,wxT("Main Menu"),icons->getSpecialBitmap(BITMAP_IMPP_ICON));
		 toolbar->AddCheckTool(ID_BUDDYLIST_BUDDY_SHOW_OFFLINE,wxT("show Offlines"),icons->getStatusIcon(OFFLINE),icons->getStatusIcon(ONLINE));
		 toolbar->AddCheckTool(ID_BUDDYLIST_GROUPS_USE,wxT("use Groups"),groupTogle);
		 toolbar->AddCheckTool(ID_BUDDYLIST_BUDDY_SHOWAVAS,wxT("show Avatare"),avasTogle);
		 toolbar->AddCheckTool(ID_BUDDYLIST_BUDDY_PRIORITY_CHANGE,wxT("show Buddies with Priority"),priority);

		 bool showOffline = dbModule.getIntValue(wxT("showOffline"),0);
		 bool useGroups = dbModule.getIntValue(wxT("useGroups"),1);
		 bool showAvas = dbModule.getIntValue(wxT("showAvas"),1);
		 bool priorityMode = dbModule.getIntValue(wxT("shownPriority"), BUDDY_PRIORITY_LOW) != BUDDY_PRIORITY_LOW;

		 toolbar->ToggleTool(ID_BUDDYLIST_BUDDY_SHOW_OFFLINE,showOffline);
		 toolbar->ToggleTool(ID_BUDDYLIST_GROUPS_USE,useGroups);
		 toolbar->ToggleTool(ID_BUDDYLIST_BUDDY_SHOWAVAS,showAvas);
		 toolbar->ToggleTool(ID_BUDDYLIST_BUDDY_PRIORITY_CHANGE,priorityMode);

		 toolbar->Realize();
	 }else{
		 wxLogDebug(wxT("BuddyList::BuddyList: Frame returned no Toolbar"));
	 }



	sizer->Add(infoPane, 0,wxEXPAND|wxALL,3);
	sizer->Add(searchField, 0,wxEXPAND|wxALL,0);
    sizer->Add(list, 1,wxEXPAND|wxALL,0);
    sizer->Add(actionPanel, 0,wxEXPAND|wxALL,0);

    rootPane->SetSizer(sizer);
    rootPane->Layout();
    Layout();

    wxRect displaySize = ::wxGetClientDisplayRect();

    wxPoint pos;
    pos.x = dbModule.getIntValue(BUDDYLIST_DB_POSITION_X,0);
    pos.y = dbModule.getIntValue(BUDDYLIST_DB_POSITION_Y,0);

    if(pos.x < displaySize.x || pos.x >= displaySize.width){
    	pos.x = 0;
    }
    if(pos.y < displaySize.y || pos.y >= displaySize.height){
    	pos.y = 0;
    }

    SetPosition(pos);

    wxSize size;
    size.SetHeight(dbModule.getIntValue(BUDDYLIST_DB_SIZE_HEIGHT,500));
    size.SetWidth(dbModule.getIntValue(BUDDYLIST_DB_SIZE_WIDTH,100));
    SetSize(size);

    impp->Connect(EVT_MESSAGE_IN,MessageEventHandler(BuddyList::onMessageIn), NULL, this);
    impp->Connect(EVT_MESSAGE_READ,MessageReadEventHandler(BuddyList::onMessageRead), NULL, this);
    impp->Connect(EVT_SETTING_CHANGED,SettingChangedEventHandler(BuddyList::onSettingChanged), NULL, this);
    impp->Connect(EVT_IMPP_COMMAND,ImppCommandEventHandler(BuddyList::onImppAction), NULL, this);

    list->Connect(wxEVT_KEY_DOWN, wxCharEventHandler(BuddyList::onKeyDown),NULL,this);

    Settings* settings = impp->getSettings();
    SettingsPage* sPage = settings->createSettingsPage(dbModule, wxT("BuddyList"));

    SettingsGroup* buddyGroup = sPage->createSettingsGroup(wxT("Buddies"));
    buddyGroup->createCheckSetting(wxT("Show offline buddies"), BUDDYLIST_DB_BUDDY_SHOW_OFFLINE);
    buddyGroup->createCheckSetting(wxT("Show avatars in buddylist"), BUDDYLIST_DB_BUDDY_SHOW_AVAS);
    buddyGroup->createCheckSetting(wxT("Dim idle buddies in buddylist"), BUDDYLIST_DB_BUDDY_DIM_IDLE);

    SettingsGroup* groupsGroup = sPage->createSettingsGroup(wxT("Groups"));
    groupsGroup->createCheckSetting(wxT("Use groups"), BUDDYLIST_DB_GROUPS_USE_GROUPS);
    groupsGroup->createCheckSetting(wxT("Hide empty groups"), BUDDYLIST_DB_GROUPS_HIDE_EMPTY);

	//create MainMenuEntry
	if(ui != NULL){
		ui->reigsterMainMenuEntryAdder(STD_BUDDYLIST_MODULE_NAME, BuddyList::addBuddyListMainMenuEntries);
		ui->getIcons()->registerActionIcon(STD_BUDDYLIST_MODULE_NAME, STD_BUDDYLIST_MODULE_SUBMENU_GROUPS, wxT("icons/main/group.png"));
	}else{
		wxLogDebug(wxT("No UserInterface found to add MainMenu entry!"));
	}


    /*
    wxAcceleratorEntry entries[1];
    entries[0].Set(wxACCEL_CTRL,  WXK_RETURN, ID_ENTER);
    wxAcceleratorTable accel(1, entries);
    SetAcceleratorTable(accel);
	*/
}

BuddyList::~BuddyList()
{
}

void BuddyList::moduleInit(){
	//nothing to do
}
void BuddyList::moduleDestroy(){
	savePosition();
	Destroy();
}

wxWindow* BuddyList::getWindow(){
	return this;
}

void BuddyList::onShowBuddiesWithPriority(wxCommandEvent & event){
	wxToolBar* toolBar = GetToolBar();

	switch(event.GetId()){
		case ID_BUDDYLIST_BUDDY_PRIORITY_CHANGE:
		{
			wxMenu menu;
			menu.Append(ID_BUDDYLIST_BUDDY_PRIORITY_ALL, wxT("show all buddies"));
			menu.Append(ID_BUDDYLIST_BUDDY_PRIORITY_JUST_HIGH, wxT("only show high priority buddies"));
			menu.Append(ID_BUDDYLIST_BUDDY_PRIORITY_NOT_LOW, wxT("don't show low priority buddies"));
			PopupMenu(&menu);
		}
			break;
		case ID_BUDDYLIST_BUDDY_PRIORITY_ALL:
			list->setShowBuddiesWithPriority(BUDDY_PRIORITY_LOW);
			if(toolBar){
				toolBar->ToggleTool(ID_BUDDYLIST_BUDDY_PRIORITY_CHANGE, false);
			}
			break;
		case ID_BUDDYLIST_BUDDY_PRIORITY_JUST_HIGH:
			list->setShowBuddiesWithPriority(BUDDY_PRIORITY_HIGH);
			if(toolBar){
				toolBar->ToggleTool(ID_BUDDYLIST_BUDDY_PRIORITY_CHANGE, true);
			}
			break;
		case ID_BUDDYLIST_BUDDY_PRIORITY_NOT_LOW:
			list->setShowBuddiesWithPriority(BUDDY_PRIORITY_NORMAL);
			if(toolBar){
				toolBar->ToggleTool(ID_BUDDYLIST_BUDDY_PRIORITY_CHANGE, true);
			}
			break;
	}
}

void BuddyList::onMainMenu(wxCommandEvent & event){
	iUserInterface* ui = Impp::exemplar()->getModuleManager()->getUserInterfaceModule();
	if(ui != NULL){
		wxMenu menu;
		ui->buildMainMenu(&menu);
		PopupMenu(&menu);
	}else{
		wxLogError(wxT("BuddyList::onMainMenu: Coudn't build Status Mainmenu no UserInterfaceModule loaded"));
	}
}

void BuddyList::onCheckTool(wxCommandEvent & event){
	Impp* impp = Impp::exemplar();
	switch(event.GetId()){
		case ID_BUDDYLIST_BUDDY_SHOW_OFFLINE:
			impp->processSettingChangedInt(dbModule, BUDDYLIST_DB_BUDDY_SHOW_OFFLINE, event.IsChecked());
		break;
		case ID_BUDDYLIST_GROUPS_USE:
			impp->processSettingChangedInt(dbModule, BUDDYLIST_DB_GROUPS_USE_GROUPS, event.IsChecked());
		break;
		case ID_BUDDYLIST_BUDDY_SHOWAVAS:
			impp->processSettingChangedInt(dbModule, BUDDYLIST_DB_BUDDY_SHOW_AVAS, event.IsChecked());
		break;
	}
}

void BuddyList::onMessageIn(MessageEvent & event){
	event.Skip();
	setUnreadMsg(event.getBuddy(), true);
}

void BuddyList::onMessageRead(MessageReadEvent & event){
	event.Skip();
	setUnreadMsg(event.getSender(), false);
}




void BuddyList::onClosed(wxCloseEvent & event){
	savePosition();
	Hide();
	//Impp::exemplar()->close();
}

void BuddyList::onSettingChanged(SettingChangedEvent & event){
	if(event.getModule() == dbModule){
		wxString setting = event.getSettingName();

		if(setting == BUDDYLIST_DB_BUDDY_SHOW_OFFLINE){
			changeShowOffline(event.IsChecked());
		}else if(setting == BUDDYLIST_DB_BUDDY_SHOW_AVAS){
			changeShowAvas(event.IsChecked());
		}else if(setting == BUDDYLIST_DB_BUDDY_DIM_IDLE){
			changeDimIdle(event.IsChecked());
		}else if(setting == BUDDYLIST_DB_GROUPS_USE_GROUPS){
			changeUseGroups(event.IsChecked());
		}else if(setting == BUDDYLIST_DB_GROUPS_HIDE_EMPTY){
			changeHideEmptyGroups(event.IsChecked());
		}else{
			event.Skip();
		}


	}else{
		event.Skip();
	}
}

void BuddyList::onImppAction(ImppCommandEvent & event){
	if(event.getModuleName() == STD_BUDDYLIST_MODULE_NAME){
		wxString actionName = event.getActionName();

		if(actionName == STD_BUDDYLIST_MODULE_MENU_GROUPS_HIDE_EMPTY){
			changeHideEmptyGroups(event.IsChecked());
		}else if(actionName == STD_BUDDYLIST_MODULE_MENU_GROUPS_USE_GROUPS){
			changeUseGroups(event.IsChecked());
		}
	}else{
		event.Skip();
	}
}

void BuddyList::savePosition(){
	wxPoint pos = GetPosition();
	dbModule.setIntValue(BUDDYLIST_DB_POSITION_X,pos.x);
	dbModule.setIntValue(BUDDYLIST_DB_POSITION_Y,pos.y);
	wxSize size = GetSize();
	dbModule.setIntValue(BUDDYLIST_DB_SIZE_WIDTH,size.GetWidth());
	dbModule.setIntValue(BUDDYLIST_DB_SIZE_HEIGHT,size.GetHeight());
}

void BuddyList::setUnreadMsg(Buddy* buddy, bool unreadMsgs){
	;
}


void BuddyList::changeHideEmptyGroups(bool hide){
	list->setHideEmptyGroups(hide);
}
void BuddyList::changeUseGroups(bool useGroups){
	GetToolBar()->ToggleTool(ID_BUDDYLIST_GROUPS_USE,useGroups);
	list->setUseGroups(useGroups);
}

void BuddyList::changeShowOffline(bool showOffline){
	GetToolBar()->ToggleTool(ID_BUDDYLIST_BUDDY_SHOW_OFFLINE,showOffline);
	list->setShowOffline(showOffline);
}

void BuddyList::changeShowAvas(bool showAva){
	GetToolBar()->ToggleTool(ID_BUDDYLIST_BUDDY_SHOWAVAS,showAva);
	list->setShowAvas(showAva);
}

void BuddyList::changeDimIdle(bool dimIdle){
	list->setDimIdle(dimIdle);
}

void BuddyList::onKeyDown(wxKeyEvent & event){
	int keyCode = event.GetKeyCode();

	if(keyCode >= 0x20 && keyCode<=0x7E){
		searchField->Show();
		sizer->Layout();
		searchField->trigger(event.GetUnicodeKey());
	}
	event.Skip(true);
}

SearchField* BuddyList::getSearchField(){
	return searchField;
}

void BuddyList::hideSearchField(){
	searchField->Hide();
	sizer->Layout();
	list->SetFocus();
	list->SetFocusFromKbd();
}

BuddyTreeList* BuddyList::getTreeList(){
	return list;
}

void BuddyList::layoutMainSizer(){
	sizer->Layout();
}

void BuddyList::addCheckSettingButton(DBModule & dbModule, const wxString & settingName, const wxString & title, const wxString & description){
	buttonList.addCheckSettingButton(dbModule, settingName, title, description);


	//buttonSizer->Add(bt,0,wxSHAPED|wxALIGN_LEFT);
	//Connect(button->id, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ChatPanel::onButton), NULL, this);
}

void wxCALLBACK BuddyList::addBuddyListMainMenuEntries(iMenu* menu, void* userData){
	iMenu* grousMenu = menu->appendOrGetSubMenu(STD_BUDDYLIST_MODULE_SUBMENU_GROUPS, wxT("Groups"), 30, wxT("Group Buddylist Settings"));

	DBModule module = Impp::exemplar()->getDatabase()->getModule(wxT("BuddyList"));

	grousMenu->appendCheckItem(STD_BUDDYLIST_MODULE_MENU_GROUPS_USE_GROUPS, wxT("Use Groups"), module.getIntValue(BUDDYLIST_DB_GROUPS_USE_GROUPS, 0), 10, wxT("Use Groups"));
	grousMenu->appendCheckItem(STD_BUDDYLIST_MODULE_MENU_GROUPS_HIDE_EMPTY, wxT("Hide Empty Groups"), module.getIntValue(BUDDYLIST_DB_GROUPS_HIDE_EMPTY, 0),20, wxT("Hide Empty Groups"));
}


}



